package com.batsoft.trade.api.core.shiro;

import com.batsoft.trade.api.common.constant.Constant;
import com.gomyb.redis.RedisService;
import lombok.Getter;
import lombok.Setter;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;

/**
 * @author <a href="mailto:hellohesir@gmail.com">Mr_He</a>
 * 自定义校验过程以及散列加密
 */
public class RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher {

    private RedisService redisService;

    public RetryLimitHashedCredentialsMatcher(RedisService redisService) {
        this.redisService = redisService;
    }

    /**
     * 自定义密码错误上限
     */
    @Getter
    @Setter
    private Integer retryMax;

    /**
     * 对该方法装饰
     */
    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) throws ExcessiveAttemptsException {
        CacheUser user = (CacheUser) info.getPrincipals().getPrimaryPrincipal();
        String username = Constant.LOGIN_SECOND + user.getUsername();
        String retryCount = redisService.get(username);
        if (retryCount == null) {
            retryCount = "0";
            redisService.set(username, retryCount, 60);
        }

        if (Integer.parseInt(retryCount) >= retryMax) {
            throw new ExcessiveAttemptsException("您已连续错误达" + retryMax + "次！请稍后再试");
        }

        redisService.incr(username);

        boolean matches = super.doCredentialsMatch(token, info);
        if (matches) {
            redisService.del(username);
        } else {
            throw new IncorrectCredentialsException("密码错误，已错误" + retryCount + "次，最多错误" + retryMax + "次");
        }
        return true;
    }

}
